#include "NNetContainer.h"

#include "Util.h"

NNetContainer::NNetContainer(int _dim, int _nhidden, int _nLabel, vector<int> _hiddenNum, double _lrate)
{
    m_Net = new QMLPNet(_dim,_nhidden,_nLabel,_hiddenNum,_lrate);
    m_Net->RandomInit();
}

NNetContainer::~NNetContainer(void)
{
    delete m_Net;
}

void NNetContainer::LoadData(string _inputFile, int _dim, int _nLabel)
{
    ifstream fin(_inputFile.c_str());
    m_LabelNum = _nLabel;
    m_Dimention = _dim;
    while (!fin.eof())
    {
        DATA_VEC dv;
        for (int i = 0; i < _dim; ++i)
        {
            double value;
            fin >> value;
            dv.push_back(value);
        }
        m_Data.push_back(dv);
        int label;
        fin >> label;
        LABEL_VEC lv;
        lv.resize(_nLabel);
        lv.assign(_nLabel, 0);
        lv[label] = 1;
        m_Label.push_back(lv);
    }
    fin.close();
}

void NNetContainer::LoadData(string _inputFile, int _dim)
{
    ifstream fin(_inputFile.c_str());
    m_LabelNum = 1;
    m_Dimention = _dim;
    while (!fin.eof())
    {
        DATA_VEC dv;
        for (int i = 0; i < _dim; ++i)
        {
            double value;
            fin >> value;
            dv.push_back(value);
        }
        m_Data.push_back(dv);

        double label;
        fin >> label;
        LABEL_VEC lv;
        lv.push_back(label);
        m_Label.push_back(lv);
    }
    fin.close();
}

void NNetContainer::Train(int _tms)
{
    for (int tms = 0; tms < _tms; ++tms)
    {
        for (int i = 0; i < m_Data.size(); ++i)
        {
            m_Net->Train(m_Data[i], m_Label[i]);
        }
    }
}

void NNetContainer::Test(string _testFile, std::ostream &_os)
{
    ifstream fin(_testFile.c_str());
    while (!fin.eof())
    {
        DATA_VEC dv;
        for (int i = 0; i < m_Dimention; ++i)
        {
            double value;
            fin >> value;
            dv.push_back(value);
        }

        if (m_LabelNum == 1)
        {
            //Regression
            double label;
            fin >> label;
            LABEL_VEC tv = m_Net->Simulate(dv);
            _os << label << " " << tv[0] << endl;
        }
        else 
        {
            //Classifier
            int label;
            fin >> label;

            LABEL_VEC tv = m_Net->Simulate(dv);
            int i = FindMax(tv);
            _os << label << " " << i << " ";
            for (int i = 0; i < tv.size(); ++i)
            {
                _os << tv[i] << " ";
            }
            _os << endl;
        }
    }
    fin.close();
}